<!-- select下拉菜单选择器插件:: -->
<!--
    <mySelect
        style='width:300px;' // 支持自定义输入框位置和样式
        placeholder='哈哈哈' //输入框的placeholder提示符
        size='small' //插件的大小 => size = 'mini' || small'(默认) || 'medium'

        url='myBrand' //输入框下拉 时的请求数据接口
        data='{type:1,appid:770}' ( 或者 :data='options' ) // 当异步请求url时, data=>接口的参数 ; 否则 为静态的固定下拉菜单的数组
        label-value='brandName-brandId' // 自定义绑定的 标签-唯一值 { label:'brandName',value:'brandId' }

        nobody // 设置 nobody 时将以父元素div进行定位 ( 默认 插入到html->body根元素下面进行定位 )

        filterable //支持输入搜索
        multiple //支持多选模式
        @remove='console(arguments)' //多选模式下的移除标签 触发的回调 => value,{
                                                                                item: vModelObj[value], //被移除的项目
                                                                                checked: vModelObj, //所有选中的 项目对象
                                                                                list: this.vList //所有下拉数组
                                                                            }
        @select='console(arguments)' //当选中一个 下拉菜单时触发 => (value,{
                                                                            exist: exist, //是否重复点击选中的项目
                                                                            label: item.label, //选中的标签
                                                                            item: lastClick = item, //选中的项目
                                                                            checked: vModelObj, //所有选中的 项目对象
                                                                            list: this.vList //所有下拉数组
                                                                        })
        myModel='select' //插入到父组件的 v-model 的key, dad['select'] = this.vModel( 双向绑定 );
        type='menu' //(可选) 支持级联选择器 的多选模式 (通过jQuery自定义DOM)
    ></mySelect>
 -->
<template>
  <div style="display: inline-block;">
    <div v-if=' type===undefined ' style="position: relative;width: 100%;">
      <el-select
        v-model="vModel"
        Aallow-create
        :filterable=" vFilterable || filterable!==undefined "
        :multiple=' vMultiple || multiple!==undefined '
        ref="mySelect"
        :placeholder="vPlaceholder||placeholder||'请选择'"
        style='position: static;margin-left: 5px;width: 100%;'
        :size=" size||'small' "
        :popper-append-to-body='vBody||nobody===undefined'
        clearable
        change="change"
        @clear="clear"
        @visible-change="ajax.sleep(20,arguments[0])"
        @remove-tag='removeTag'
      >
        <el-option
          v-for="(item,index) in vList"
          :label="item.label"
          :value=" item.value!==undefined ? item.value : index "
          :key="index"
          :disabled="!vList.length || innerMultiple"
          @click.native='innerClick(item)'
        >
          <span v-if="item===false">没有数据</span>
          <span v-else-if="item===true" class="el-icon-loading" id="myWaitDown"></span>
          <span v-else>{{ item.label||item }}</span>
        </el-option>
      </el-select>
    </div>

    <el-cascader
      ref="mySelect"
      popper-class='myCaseMenu'
      id='myCaseMenu'
      :separator=' multiple ? "、" : "/" '
      :show-all-levels=' !multiple '
      v-else
      v-model='tempClass'
      :style=' width ? "width:"+width+"px" : size==="medium" ? "width:300px;" : "width:160px;"'
      :placeholder=" placeholder || '请勾选' "
      :size='size||"small" '
      afilterable
      clearable
      expand-trigger=hover
      :options="allClass"
      @change='selectShopClass'
      @visible-change='showAllClass'
      @active-item-change="handleItemChange"
      :props="{value: 'classificationId', label: 'classificationName'}"
    ></el-cascader>

  </div>
</template>

<script>
  const delKey = G.deleteKey;
  const api = $.api;
  var dad, myModel, url, data, isStatic, label = 'label', value = 'value', lastClick;
  var $refs;
  export default {
    ref: false,
    global: false,
    name: 'mySelect',
    props: ['type', 'width', 'size', 'placeholder', 'nobody', 'filterable', 'multiple', 'url', 'labelValue', 'data', 'myModel', 'dad', 'son', 'dadSon'],
    data: function () {
      return {
        vModel: '',
        vModelObj: Object.create(null),
        vList: [],
        vPlaceholder: '',
        vFilterable: false,
        vMultiple: false,
        vBody: false,

        // fixedModel: '',
        tempClass: [],
        allClass: [],

        innerMultiple: false,
        globalEmpty: {},
        globalSelect: {},
        lastLast: null,

        globalMenu: {},

      }
    },
    watch: {
      vModel(val) {
        if (this.innerSet) return delete this.innerSet;
        myModel !== undefined && (
          this.innerSet = true,
            dad[myModel] = val
        );
        // console.warn(val,myModel,dad,dad[myModel]);
      }
    },
    methods: {
      selectShopClass(id) {
        if (this.limit !== '2') {
          const find = id[2];
          // console.error(find,this.No2);
          if (find !== undefined) {
            const No2 = this.No2;
            var findObj = No2 ? No2.children.find(v => v.classificationId === find) : null;
            findObj = findObj ? {
              value: findObj.classificationId,
              label: findObj.classificationName
            } : '';
            this.myModel && (this.$parent[this.myModel] = findObj);
            findObj ? this.$emit('select', findObj.value, findObj.label) : this.$emit('select', '');
          } else {
            this.myModel && (this.$parent[this.myModel] = '');
            this.$emit('select', '');
          }
          ;
        } else {
          const find = id[1];
          if (find !== undefined) {
            const No2 = this.No1;
            var findObj = No2 ? No2.find(v => v.classificationId === find) : null;
            findObj = findObj ? {
              value: findObj.classificationId,
              label: findObj.classificationName
            } : '';
            this.myModel && (this.$parent[this.myModel] = findObj);
            findObj ? this.$emit('select', findObj.value, findObj.label) : this.$emit('select', '');
          } else {
            this.myModel && (this.$parent[this.myModel] = '');
            this.$emit('select', '');
          }
          ;
        }
      },
      handleItemChange: async function (val) {
        var next, find;
        if (val.length === 1) {
          next = val[0];
          find = this.allClass.find(v => v.classificationId === next);
          /*if(find && this.limit==='2') {
              this.No2 = find.children;
              console.warn(this.allClass,find,this.No2,find.children);
          };*/
        } else {
          next = val[1];
          const one = val[0];
          this.No2 = find = forEach(this.allClass, v => {
            if (v.classificationId !== one) return;
            return v.children.find(v2 => v2.classificationId === next);
          });
          // console.error(find);
        }
        ;
        if (!find) return;
        var data = await myAjax(
          api.getTwoShop,
          {
            level: val.length === 1 ? 2 : 3,
            parentId: next,
            storeId: localStorage.getItem('storeId'),
          }
        );
        if (!data) return;
        const multiple = this.multiple;
        if (val.length === 1) {
          if (multiple !== '2') {
            // console.error(data.data);
            if (this.limit !== '2') return this.No1 = find.children = data.data.map(v => (v.children = [], v));
            this.No1 = find.children = data.data;
            // console.error(this.No2);
            return;
          }
          ;

          // console.error(multiple);

          (data = data.data).forEach(v => v.disabled = true);
          var all = $('body>div.myCaseMenu').children('ul').eq(1).children('li').removeClass('checkedLiLi').unbind('click');
          all.children('i').remove();
          find.children = data;
          this.$nextTick(() => {
            // console.log(all);
            // setTimeout(()=>fire(),100);
            // const fire = () =>{
            const allMenu = $('body>div.myCaseMenu').children('ul').eq(1).children('li').click((e) => {
              const nodeName = e.target.nodeName;
              e = $(e.target);
              const target = nodeName !== 'LI' ? e.closest('li')[0] : e[0];
              e = $(target);
              const index = forEach(allMenu, (v, i) => v === target && i);
              const item = data[index];
              // console.error( switch,data[switch] );

              const i = e.children('i');
              const has = !e.hasClass('checkedLiLi');
              !i.length
                ? e.append('<i class=el-icon-check>')
                : i.css('display', has ? '' : 'none');
              e.toggleClass('checkedLiLi');

              // console.log(has,e[0],i,item.classificationName,item,switch,data,allMenu);

              const myCaseMenu = $('#myCaseMenu');
              const myShangSelect = myCaseMenu.children('#myShangSelect');
              if (!item) return;
              const classificationId = item.classificationId;
              const globalMenu = this.globalMenu;

              const remove = GLOBAL.remove = function (myShangSelect) {
                // console.log(myShangSelect,myShangSelect[0].scrollWidth,myShangSelect[0].offsetWidth);
                myShangSelect[0].scrollWidth > myShangSelect[0].offsetWidth
                  ? myShangSelect.closest('#myGood').addClass('myCaseMenu')
                  : myShangSelect.closest('#myGood').removeClass('myCaseMenu');
              };

              if (!myShangSelect.length) {
                $(`
                                        <div id='myShangSelect'>
                                            <div id=myCase${classificationId}>
                                                ${item.classificationName}
                                                <i class="el-icon-close" onclick="this.parentNode.outerHTML='';GLOBAL.remove( $('#myShangSelect') );"></i>
                                            </div>
                                        </div>
                                    `).appendTo(myCaseMenu).click(e => e.stopPropagation());
                globalMenu[classificationId] = item;
              } else {

                remove(myShangSelect);

                if (globalMenu.hasOwnProperty(classificationId)) {
                  if (has) return;
                  myShangSelect.children('#myCase' + classificationId).remove();
                  delete globalMenu[classificationId];
                } else {
                  myShangSelect.append(`
                                            <div id=myCase${classificationId} >
                                                ${item.classificationName}
                                                <i class="el-icon-close" onclick="this.parentNode.outerHTML='';GLOBAL.remove( $('#myShangSelect') );"></i>
                                            </div>
                                        `);
                  globalMenu[classificationId] = item;
                }
                ;
                myShangSelect.scrollLeft(myShangSelect[0].scrollWidth);
              }
              ;
              /*const input = $('#myCaseMenu').find('input.el-input__inner').attr('readonly',false);
              const value = input.val();

              console.error( input.val( this.lastValue = !value?item.classificationName:value+'、'+item.classificationName ) );*/
            });
            // };

          });
          return;
        }
        ;

        /*if(val.length===2) {
            if(this.multiple) {
                data.data.forEach(v=>v.disabled=true);
            };
            return find.children =  data.data;
        };*/
        // console.log(val);

        if (multiple) {
          data.data.forEach(v => v.disabled = true);
          var all = $('body>div.myCaseMenu').children('ul').eq(2).children('li').removeClass('checkedLiLi').unbind('click');
          all.children('i').remove();
        }
        ;
        // setTimeout( ()=>{
        data = find.children = data.data;
        // if(this.multiple) fire();
        // }, 200 );
        // return;
        if (multiple) {
          this.$nextTick(() => {
            // console.log(all);
            // setTimeout(()=>fire(),100);
            // const fire = () =>{
            const allMenu = $('body>div.myCaseMenu').children('ul').eq(2).children('li').click((e) => {
              const nodeName = e.target.nodeName;
              e = $(e.target);
              const target = nodeName !== 'LI' ? e.closest('li')[0] : e[0];
              e = $(target);
              const index = forEach(allMenu, (v, i) => v === target && i);
              const item = data[index];
              // console.error( switch,data[switch] );

              const i = e.children('i');
              const has = !e.hasClass('checkedLiLi');
              !i.length
                ? e.append('<i class=el-icon-check>')
                : i.css('display', has ? '' : 'none');
              e.toggleClass('checkedLiLi');

              // console.log(has,e[0],i,item.classificationName,item,switch,data,allMenu);

              const myCaseMenu = $('#myCaseMenu');
              const myShangSelect = myCaseMenu.children('#myShangSelect');
              if (!item) return;
              const classificationId = item.classificationId;
              const globalMenu = this.globalMenu;

              const remove = GLOBAL.remove = function (myShangSelect) {
                // console.log(myShangSelect,myShangSelect[0].scrollWidth,myShangSelect[0].offsetWidth);
                myShangSelect[0].scrollWidth > myShangSelect[0].offsetWidth
                  ? myShangSelect.closest('#myGood').addClass('myCaseMenu')
                  : myShangSelect.closest('#myGood').removeClass('myCaseMenu');
              };

              if (!myShangSelect.length) {
                $(`
                                        <div id='myShangSelect'>
                                            <div id=myCase${classificationId}>
                                                ${item.classificationName}
                                                <i class="el-icon-close" onclick="this.parentNode.outerHTML='';GLOBAL.remove( $('#myShangSelect') );"></i>
                                            </div>
                                        </div>
                                    `).appendTo(myCaseMenu).click(e => e.stopPropagation());
                globalMenu[classificationId] = item;
              } else {

                remove(myShangSelect);

                if (globalMenu.hasOwnProperty(classificationId)) {
                  if (has) return;
                  myShangSelect.children('#myCase' + classificationId).remove();
                  delete globalMenu[classificationId];
                } else {
                  myShangSelect.append(`
                                            <div id=myCase${classificationId} >
                                                ${item.classificationName}
                                                <i class="el-icon-close" onclick="this.parentNode.outerHTML='';GLOBAL.remove( $('#myShangSelect') );"></i>
                                            </div>
                                        `);
                  globalMenu[classificationId] = item;
                }
                ;
                myShangSelect.scrollLeft(myShangSelect[0].scrollWidth);
              }
              ;
              /*const input = $('#myCaseMenu').find('input.el-input__inner').attr('readonly',false);
              const value = input.val();

              console.error( input.val( this.lastValue = !value?item.classificationName:value+'、'+item.classificationName ) );*/
            });
            // };

          });
        }
        ;
        // console.error(find);
      },

      showAllClass: async function (bool) {
        if (!bool) {
          return;
        }
        ;
        var data = await myAjax(
          api.getOneShop
        );
        if (!data) return;
        (data = data.data).forEach(v => v.children = []);
        this.allClass = data;
        // console.error(data);
      },

      removeTag(value) {
        // console.error(item,this.vModel);
        const vModelObj = this.vModelObj;
        this.$emit('remove', value, {
          item: vModelObj[value],
          checked: vModelObj,
          list: this.vList
        });
        delete vModelObj[value];
      },

      focus() {
        $refs.mySelect.$el.click();
      },

      clear(val) {
        lastClick = null;
        delKey(this.vModelObj);
        this.$emit('select', '');
      },

      innerClick(item) {
        if (typeof item === 'boolean') return this.vModel = '';
        const value = item.value;
        const vModelObj = this.vModelObj;

        const exist = vModelObj[value] !== undefined;
        exist ? delete vModelObj[value] : vModelObj[value] = item;
        this.$emit('select', value, {
          exist: exist,
          label: item.label,
          item: lastClick = item,
          checked: vModelObj,
          list: this.vList
        });
      },

      ajax: async function (bool) {
        // console.warn(bool,this.vModel);
        if (bool === false) {
          // this.innerMultiple = false;
          return;
        }
        ;

        if (isStatic) return;

        // console.warn(data,this.data);
        lastClick && lastClick.index === 0 && (this.vModel = lastClick.label);

        this.vList = [true];

        Post(
          !/^(http|https):/i.test(url) ? api[url] : url,
          ({
            appkeyid: 'mofanglj',
            appkeyvalue: 'mofanglj2018'
          }).with(data),
          (res, err) => {
            // console.error(res,label,value);
            res = res.data;
            setTimeout(() => {
              this.vList = !res || !res.length ? [false] : res.map((v, i) => {
                return {label: v[label], value: v[value], index: i};
              });
            }, 100);
          }
        );
      },

    },
    created() {
      dad = this.parseDadSon('mySelect');
      myModel = this.myModel;
      if (myModel) {
        dad.myBind(myModel, val => {
          if (this.innerSet) {
            delete this.innerSet;
            return;
          }
          console.error(val,this.vList);
          this.innerSet = true;
          this.vModel = val;
          if (!val && val !== 0) lastClick = null, delKey(this.vModelObj);
        });
        // dad[myModel] = init;
      }
      ;

      url = this.url;
      data = this.data;

      // console.warn(data);
      var labelValue = this.labelValue;
      labelValue && (labelValue = labelValue.split('-'), label = labelValue[0], value = labelValue[1]);

      if (!url && data && data.length) {
        this.vList = mapArr(data, (v, i) => {
          if (v === null) return;
          return typeof v === 'object'
            ? {label: v[label], value: v[value], index: i}
            : {label: v, value: i, index: i};
        });
        // console.error(this.vList);
        isStatic = true;
      }
      ;

      $refs = this.$refs;

      // myAjax = Ajax.bind(this);

    },
    mounted() {

    },

  }
</script>

<style>
  .myCaseMenu .el-input__inner {
    height: 55px !important;
  }

  .el-cascader-menu__item.is-disabled {
    cursor: pointer !important;
    color: #606266 !important;
  }

  .el-cascader-menu__item.is-disabled:hover {
    background: rgb(244, 246, 249) !important;
  }

  #myShangSelect {
    position: absolute;
    left: 0;
    top: 0;
    background: white;
    /*border-radius: 18px;*/
    /* line-height: 30px; */
    /* padding: 0 5px; */
    box-sizing: border-box;
    display: flex;
    /*justify-content: center;*/
    /*align-items: center;*/
    margin-top: 5px;
    margin-left: 7px;
    /*max-width: 265px;*/
    max-width: calc(100% - 37px);
    white-space: nowrap;
    overflow: auto;
    z-index: 777;
  }

  #myShangSelect > div {
    line-height: 30px;
    height: 30px;
    background: #e8e8e8;
    border-radius: 2px;
    padding: 0 7px;
    display: inline-block;
    margin-right: 10px;
  }

  #myShangSelect i {
    color: red;
    cursor: pointer;
  }

  #myShangSelect i:hover {
    opacity: 0.7;
    font-weight: bold;
  }

  #myGood input {
    height: 40px;
  }

  #myGood .el-select-dropdown__item.is-disabled {
    color: #2D3E50;
    cursor: pointer;
  }

  #myGood .el-select-dropdown__item.is-disabled:hover {
    background: #a2c8f9 !important;
    /*background: #6CCDEE !important;*/
  }

  #myGood .el-select-dropdown__item.is-disabled.checkedLiLi, .myCaseMenu .checkedLiLi {
    background: #e0e9f3 !important;
  }

  #myGood .el-select-dropdown__item.is-disabled.checkedLiLi > i, .myCaseMenu .checkedLiLi > i {
    font-size: 15px;
    font-weight: bold;
    color: #409eff;
    position: absolute;
    right: 16px;
    top: 50%;
    margin-top: -8px;
  }

  #myGood .checkedLiLi.is-disabled:hover {
    background: #ccdbea !important;
  }
</style>
